<template>
  <!-- shadow	设置阴影显示时机	string	always/hover/never	默认值always -->
  <el-card shadow="hover">
    <!-- 添加品牌按钮 -->
    <!-- <el-button type="primary" :icon="Plus" @click="showTrademarkDialog" -->
    <el-button
      type="primary"
      :icon="Plus"
      @click="showTrademarkDialog({ id: 0, logoUrl: '', tmName: '' })"
      >添加品牌</el-button
    >
    <!-- 品牌表格 -->
    <!-- 
      data	显示的数据
      border	是否带有纵向边框
      row-key	行数据的 Key，用来优化 Table 的渲染 
    -->
    <el-table
      :data="trademarkList"
      border
      row-key="id"
      class="mt-20"
      v-loading="loading"
    >
      <!-- 
        el-table-column 列组件 （决定渲染几列）
        type	对应列的类型。如果设置了 index 则显示该行的索引（从 1 开始计算）
        label	显示的标题
        width	对应列的宽度
        align	对齐方式 	left/center/right

        如果想要渲染纯文本数据，prop
        如果想要渲染其他结构，插槽
       -->
      <el-table-column type="index" label="序号" width="60" align="center" />
      <el-table-column prop="tmName" label="品牌名称" />
      <el-table-column label="品牌LOGO" prop="logoUrl">
        <!-- 需要获取操作当前的行元素，可以通过v-slot或slot-scope获取 -->
        <!-- 自定义列的内容，参数为{ row, column, $index }  row: 获取行数据 -->
        <!-- <template v-slot="scope"> -->
        <template v-slot="{ row }">
          <el-image
            fit="fill"
            loading="lazy"
            class="trademark-logo"
            :src="row.logoUrl"
          >
            <!-- 具名插槽：图片加载失败时显示的内容 -->
            <template #error>
              <div class="image-slot">
                <el-icon><icon-picture></icon-picture></el-icon>
              </div>
            </template>
          </el-image>
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <!-- 通过插槽传递渲染的内容 -->
        <!-- 需要获取操作当前的行元素，可以通过v-slot或slot-scope获取 row: 获取这一行数据 -->
        <template v-slot="{ row }">
          <el-button
            type="warning"
            :icon="Edit"
            size="small"
            @click="showTrademarkDialog(row)"
          />
          <el-button
            type="danger"
            :icon="Delete"
            size="small"
            @click="delTrademarkList(row)"
          />
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页器 -->
    <!-- 
      current-page	当前页数，支持 v-model 双向绑定
      page-size	每页显示条目个数，支持 v-model 双向绑定
      page-sizes	每页显示个数选择器的选项设置
      layout	组件布局，子组件名用逗号分隔
      total	总条目数

      size-change	page-size改变时触发
      current-change	current-page改变时触发
     -->
    <el-pagination
      class="mt-20"
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :page-sizes="[3, 6, 9, 12]"
      layout="prev, pager, next, jumper, ->, sizes, total"
      :total="total"
      @size-change="getTrademarkList"
      @current-change="getTrademarkList"
    />

    <!-- Dialog 部分 -->
    <el-dialog v-model="dialogVisible" :show-close="false">
      <template #header="{ close }">
        <div class="my-header">
          <!-- id初始值为0，根据id动态展示对话框的标题 -->
          <h3 :style="{ margin: mr, fontWeight: fontweight }">
            {{ trademarkFormData.id ? "修改品牌" : "添加品牌" }}
          </h3>
          <el-button type="danger" @click="close">
            <el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
            Close
          </el-button>
        </div>
      </template>
      <el-form
        label-width="100px"
        ref="trademarkFormRef"
        :model="trademarkFormData"
        :rules="trademarkFormRules"
      >
        <el-form-item label="品牌名称" prop="tmName">
          <el-input
            class="trademark-input"
            placeholder="请输入品牌名称"
            v-model="trademarkFormData.tmName"
          />
        </el-form-item>
        <el-form-item label="品牌LOGO" prop="logoUrl">
          <!-- 
            action 上传图片服务器地址
              action="/admin/product/fileUpload" 不行，没有服务器地址
              action="http://gmall-h5-api.atguigu.cn/admin/product/fileUpload" 不行，跨域
              action="/app-dev/admin/product/fileUpload" 不行，本地开发可以，上线不行（上线请求前缀变了，变成/app-prod）
              请求前缀需要从 import.meta.env.VITE_API_URL 获取
            :show-file-list="false" 是否能上传多张图片（false不能上传多张图片）
            :on-success 上传图片成功触发函数
            :before-upload 上传图片之前触发函数（限制图片的大小和类型）
           -->
          <el-upload
            class="avatar-uploader"
            :action="BASE_URL + '/admin/product/upload'"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img
              v-if="trademarkFormData.logoUrl"
              :src="trademarkFormData.logoUrl"
              class="avatar"
            />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            <template #tip>
              <div class="el-upload__tip">
                只能上传jpg/png文件，且不超过200kb
              </div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">取消</el-button>
          <el-button type="primary" @click="addTrademark"> 确定 </el-button>
        </div>
      </template>
    </el-dialog>
  </el-card>
</template>

<script lang="ts">
export default {
  name: "XTrademark",
};
</script>

<script lang="ts" setup>
// 引入element plus的icon 图标
import {
  Plus,
  Edit,
  Delete,
  Picture as IconPicture,
} from "@element-plus/icons-vue";

// 引入对话框相关内容
import { ElButton, ElDialog, ElMessage, ElMessageBox } from "element-plus";
import { CircleCloseFilled } from "@element-plus/icons-vue";
// 表单相关
import type { UploadProps } from "element-plus";
import { ref, reactive, onMounted } from "vue";

// ts类型
import type {
  TrademarkItem,
  TrademarkList,
} from "@/api/product/model/trademarkModel";

// 品牌列表请求Api
import {
  GetTrademarkListApi,
  AddTrademarkApi,
  UpdateTrademarkApi,
  DeleteTrademarkApi,
} from "@/api/product/trademark";

// 上传图片前触发的回调
import { beforeAvatarUpload } from "@/utils/tools";

const mr = ref(0);
const fontweight = ref(400);

/*************** 品牌列表分页器相关 ****************/
// 品牌表格渲染数据
const trademarkList = ref<TrademarkList>([]);
// 当前页码
const currentPage = ref(1);
// 每页条数
const pageSize = ref(3);
// 总数
const total = ref(0);
// 表格数据请求加载效果
const loading = ref(false);

// 获取品牌列表数据
const getTrademarkList = async () => {
  // 发起请求 开启表格加载效果
  loading.value = true;
  // 发起匹配列表数据请求
  const res = await GetTrademarkListApi(currentPage.value, pageSize.value);
  // console.log(res);
  trademarkList.value = res.records;
  total.value = res.total;
  // 数据请求成功关闭加载效果
  loading.value = false;
};

// 组件一渲染就发起请求
onMounted(getTrademarkList);

// const handleSizeChange = (val: number) => {
//   // console.log(`${val} items per page`);
//   getTrademarkList();
// };
// const handleCurrentChange = (val: number) => {
//   // console.log(`current page: ${val}`);
//   getTrademarkList();
// };

/************* 添加品牌对话框显示&隐藏 **************/
// 对话框的显示&&隐藏
const dialogVisible = ref(false);

// 显示对话框函数
// const showTrademarkDialog = () => {
//   trademarkFormData.id = 0;
//   trademarkFormData.logoUrl = "";
//   trademarkFormData.tmName = "";
//   // 显示对话框
//   dialogVisible.value = true;
//   // 清空表单校验结果
//   trademarkFormRef.value.clearValidate();
// };

// 封装品牌对话框函数 添加&&修改
const showTrademarkDialog = (row: TrademarkItem) => {
  // 将表单数据赋值为当前行的数据
  trademarkFormData.id = row.id;
  trademarkFormData.logoUrl = row.logoUrl;
  trademarkFormData.tmName = row.tmName;
  // 显示对话框
  dialogVisible.value = true;

  // 清空表单校验结果
  // trademarkFormRef.value.clearValidate();

  // Uncaught TypeError: Cannot read properties of undefined (reading 'clearValidate')
  // 表单校验报错：第一次 el-form 还未渲染，点击显示对话框 立即清空表单校验，获取不到表单实例，从而报错
  // 解决方法：可选链，判断表单实例是否有值
  trademarkFormRef.value?.clearValidate();
};

// 点击取消按钮
const cancel = () => {
  dialogVisible.value = false;
};

// 点击确定按钮
const addTrademark = async () => {
  // 1. 校验整个表单
  /*
    校验通过，promise对象为成功状态
    校验失败，promise对象为失败状态
    async函数中只要有一个promise变为失败，则退出整个函数，promise变为成功状态，继续执行以下代码
  */
  await trademarkFormRef.value.validate();

  // 图片上传成功，校验失败的信息还在，需要在图片上传成功的回调中清空表单校验信息

  // 2. 表单校验成功，发送品牌信息添加请求
  // const { tmName, logoUrl } = trademarkFormData;
  const { tmName, logoUrl, id } = trademarkFormData;
  // 判断是添加还是修改操作
  if (id) {
    // 修改
    await UpdateTrademarkApi(trademarkFormData);
  } else {
    // 添加
    await AddTrademarkApi(tmName, logoUrl);
  }
  // 提示添加成功信息
  // ElMessage.success("添加品牌信息成功！");
  ElMessage.success((`${id}` ? "修改" : "添加") + "品牌信息成功！");
  // 关闭对话框
  dialogVisible.value = false;
  // 更新页面数据
  getTrademarkList();
};

// 点击删除按钮
const delTrademarkList = (row: TrademarkItem) => {
  // 提示用户确认触发的动作，并询问是否进行此操作
  // 调用 ElMessageBox.confirm 方法以打开 confirm 框。它模拟了系统的 confirm。
  ElMessageBox.confirm(
    `您确定要删除${row.tmName}吗？继续此操作...`,
    "Warning",
    {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    }
  )
    .then(async () => {
      // 点击确认按钮触发回调
      await DeleteTrademarkApi(row.id);
      // 更新页面数据
      getTrademarkList();
      // ElMessage({
      //   type: "success",
      //   message: "完成删除",
      // });
      ElMessage.success("删除成功！");
    })
    .catch((error) => {
      // console.log(error);
      if (error === "cancel") {
        ElMessage({
          type: "info",
          message: "取消删除",
        });
      }
      // ElMessage({
      //   type: "info",
      //   message: "取消删除",
      // });
    });
};

// 对话框 定义表单数据和校验规则
// 用来获取el-form组件实例对象
const trademarkFormRef = ref();
// 表单的数据
const trademarkFormData = reactive({
  // 表单参数名称参考接口文档
  // 初始化id
  id: 0,
  // 品牌logo
  logoUrl: "",
  // 品牌名称
  tmName: "",
});

// 表单校验规则
const trademarkFormRules = reactive({
  tmName: [
    {
      // 必填项
      required: true,
      // 校验失败，错误信息提示
      message: "请输入品牌名称",
      // 触发表单校验的时机：失去焦点
      trigger: "blur",
    },
    {
      min: 2,
      max: 10,
      message: "品牌名称长度必须为2~10位",
      trigger: "blur",
    },
  ],
  logoUrl: [
    {
      // 必填项
      required: true,
      // 校验失败，错误提示信息
      message: "请上传图片LOGO",
    },
  ],
});

/*********** 图片上传功能 **********/
// 请求前缀
const BASE_URL = import.meta.env.VITE_API_URL;

// const imgUrl = ref("");

// 图片上传成功
const handleAvatarSuccess: UploadProps["onSuccess"] = (response) => {
  // 更新数据
  // imgUrl.value = response.data;
  trademarkFormData.logoUrl = response.data;
  // console.log(imgUrl);
  // 清空表单校验失败的信息
  // trademarkFormRef.value?.clearValidate(); // 清空所有表单项的校验信息
  trademarkFormRef.value.clearValidate(["logoUrl"]); // 清空logoUrl表单项的校验信息
};

// 图片上传之前触发的回调
// 封装公共函数utils/tools
</script>

<style scoped>
.my-header {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.trademark-logo {
  width: 150px;
  height: 100px;
}

.trademark-input {
  width: 400px;
}

.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}

.avatar-uploader :deep(.el-upload) {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader :deep(.el-upload:hover) {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>

<!-- <style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style> -->
